#define N 150
#define THRESHOLD 6

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>
#include <limits.h>

typedef struct _iris
{
    double data[4];
    int classification;
}iris;

typedef struct _interval
{
    double low;
    double high;
}interval;

typedef struct _internode
{
    interval data;
    struct _internode *next;
}internode;

int compare0(const void *arg1, const void *arg2)
{
    const iris *elem1 = (const iris *)arg1, *elem2 = (const iris *)arg2;
    if (elem1->data[0] < elem2->data[0])
        return -1;
    if (elem1->data[0] > elem2->data[0])
        return 1;
    return 0;
}

int compare1(const void *arg1, const void *arg2)
{
    const iris *elem1 = (const iris *)arg1, *elem2 = (const iris *)arg2;
    if (elem1->data[1] < elem2->data[1])
        return -1;
    if (elem1->data[1] > elem2->data[1])
        return 1;
    return 0;
}

int compare2(const void *arg1, const void *arg2)
{
    const iris *elem1 = (const iris *)arg1, *elem2 = (const iris *)arg2;
    if (elem1->data[2] < elem2->data[2])
        return -1;
    if (elem1->data[2] > elem2->data[2])
        return 1;
    return 0;
}

int compare3(const void *arg1, const void *arg2)
{
    const iris *elem1 = (const iris *)arg1, *elem2 = (const iris *)arg2;
    if (elem1->data[3] < elem2->data[3])
        return -1;
    if (elem1->data[3] > elem2->data[3])
        return 1;
    return 0;
}

int (*compare[])(const void *, const void *) = {compare0, compare1, compare2, compare3};

iris irisdata[N];
internode *interlist = NULL;
int len;    //length of interlist, quantity of intervals

int inputdata()
{
    char strclass[20];
    int i;

    for (i=0; i<N; ++i)
    {
        scanf("%lf,%lf,%lf,%lf,%s", &irisdata[i].data[0], &irisdata[i].data[1], &irisdata[i].data[2], &irisdata[i].data[3], strclass);
        if (!strcmp(strclass, "Iris-setosa"))
            irisdata[i].classification = 0;
        else
            if (!strcmp(strclass, "Iris-versicolor"))
                irisdata[i].classification = 1;
            else
                if (!strcmp(strclass, "Iris-virginica"))
                    irisdata[i].classification = 2;
    }
    return 0;
}

int initInterlist(int n)
{
    internode *curr, *next;
    int i;
    
    //free existed interval list
    curr = interlist;
    while (curr)
    {
        next = curr->next;
        free(curr);
        curr = next;
    }
    
    //sort iris data
    qsort(irisdata, N, sizeof(*irisdata), compare[n]);

    //create new interval list
    interlist = (internode *)malloc(sizeof(*interlist));
    interlist->next = NULL;
    curr = interlist;
    len = 0;
    for (i=0; i<N; ++i)
    {
        if (len == 0 || irisdata[i].data[n] != curr->data.high)
        {
            next = (internode *)malloc(sizeof(*next));
            next->data.low = next->data.high = irisdata[i].data[n];
            next->next = NULL;
            curr->next = next;
            curr = next;
            len += 1;
        }
    }

    return 0;
}

double chi_square(int n, interval inter1, interval inter2)
{
    double chi_square_table[3][7] = {0};
    double ans = 0;
    int i, j;
    
    //fill data into chi-square table
    for (i=0; i<N; ++i)
    {
        if (inter1.low <= irisdata[i].data[n] && irisdata[i].data[n] <= inter1.high)
        {
            chi_square_table[0][irisdata[i].classification] += 1;
            continue;
        }
        if (inter2.low <= irisdata[i].data[n] && irisdata[i].data[n] <= inter2.high)
        {
            chi_square_table[1][irisdata[i].classification] += 1;
            continue;
        }
        if (irisdata[i].data[n] > inter1.high && irisdata[i].data[n] > inter2.high)
            break;
    }
    //i for row, j for col
    for (j=0; j<3; ++j)
        chi_square_table[2][j] = chi_square_table[0][j] + chi_square_table[1][j];
    for (i=0; i<3; ++i)
        chi_square_table[i][6] = chi_square_table[i][0] + chi_square_table[i][1] + chi_square_table[i][2];
    for (i=0; i<2; ++i)
        for (j=3; j<6; ++j)
            if (!(chi_square_table[i][j] = chi_square_table[i][6] * chi_square_table[2][j-3] / chi_square_table[2][6]))
                chi_square_table[i][j] = 0.1;

    for (i=0; i<2; ++i)
        for (j=0; j<3; ++j)
            ans += pow(chi_square_table[i][j] - chi_square_table[i][j+3], 2) / chi_square_table[i][j+3];

    return ans;
}

int chimerge(int n) //return: 1 for stop, 0 for continue
{
    internode *curr, *next, *flag, *tmp;
    double minchi = LLONG_MAX, chi;

    curr = interlist->next;
    if (!curr)
        return 1;
    next = curr->next;
    if (!next)
        return 1;

    while (next)
    {
        chi = chi_square(n, curr->data, next->data);
        if (chi < minchi)
        {
            minchi = chi;
            flag = curr;
        }
        curr = next;
        next = next->next;
    }
    tmp = flag->next;
    flag->data.high = tmp->data.high;
    flag->next = tmp->next;
    free(tmp);

    len -= 1;
    if (len == THRESHOLD)
        return 1;

    return 0;
}

int outputres(int n)
{
    internode *curr = interlist->next;

    printf("CASE %d:\n", n);
    while (curr)
    {
        printf("[%.1lf, %.1lf]\n", curr->data.low, curr->data.high);
        curr = curr->next;
    }
    printf("END OF CASE %d.\n\n", n);

    return 0;
}

int main()
{
    int i;

    inputdata();

    for (i=0; i<4; ++i)
    {
        initInterlist(i);
        while (!chimerge(i));
        outputres(i);
    }

    return 0;
}
